package com.gxar.quick.ar.server.base.reference;

import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gxar.common.entity.login.UserProfile;
import com.gxar.quick.ar.server.base.common.constant.UserConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.util.*;

/**
 * 用户远程调用
 *
 * @author linsy
 * @version 1.0
 * @created 2023/6/27 14:54
 */
@Component
@Slf4j
public class UserReference {

    private final String QUICK_AR_APP = "quickar";
    private final String PLATFORM = "2";
    private final String APP_ID = "ooel58faxy89fs";
    private final String APP_SECRET = "fxds69&fd%fxdfd@7dx";

    /**
     * 用户信息服务
     *
     * @param userId   用户ID
     * @param token    token
     * @param app      app
     * @param platform platform
     * @return
     */
    public JSONObject profileService(String userId, String token, String app, String platform) {
        // 构建范化调用服务
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, String> params = new HashMap<>();
        Map<String, String> paramJson = new HashMap<>();
        paramJson.put("service", UserConstant.PROFILE_SERVICE);
        paramJson.put("user_id", userId);
        paramJson.put("token", token);
        paramJson.put("app", StringUtils.isNotBlank(app) ? app : QUICK_AR_APP);
        paramJson.put("platform", StringUtils.isNotBlank(platform) ? platform : PLATFORM);
        params.put("params", JSON.toJSONString(paramJson));
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        Object userServiceObject = genericService.$invoke("dubboRpc", paramTypes, paramValues);
        if (Objects.nonNull(userServiceObject)) {
            log.info("batchProfileByAuthorize response: {}", JSON.toJSONString(userServiceObject));
            return JSON.parseObject(JSON.toJSONString(userServiceObject));
        }
        return null;
    }

    /**
     * 校验用户登录状态
     *
     * @param userId   用户ID
     * @param token    token
     * @param app      app
     * @param platform platform
     * @return 响应
     */
    public JSONObject checkSessionService(String userId, String token, String app, String platform) {
        // 构建范化调用服务
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, String> params = new HashMap<>();
        Map<String, String> paramJson = new HashMap<>();
        paramJson.put("service", UserConstant.CHECK_SESSION_SERVICE);
        paramJson.put("user_id", userId);
        paramJson.put("token", token);
        paramJson.put("app", StringUtils.isNotBlank(app) ? app : QUICK_AR_APP);
        paramJson.put("platform", StringUtils.isNotBlank(platform) ? platform : PLATFORM);
        params.put("params", JSON.toJSONString(paramJson));
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        Object userServiceObject = genericService.$invoke("dubboRpc", paramTypes, paramValues);
        if (Objects.nonNull(userServiceObject)) {
            log.info("batchProfileByAuthorize response: {}", JSON.toJSONString(userServiceObject));
            return JSON.parseObject(JSON.toJSONString(userServiceObject));
        }
        return null;
    }

    /**
     * 批量查询用户授权
     *
     * @param userId   用户ID
     * @param app      app
     * @param platform 平台
     * @return
     */
    public void writeoffWithAuthorize(String app, String platform, Long userId) {
        // 构建范化调用服务
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, String> params = new HashMap<>();
        Map<String, String> paramJson = new TreeMap<>();
        paramJson.put("user_id", String.valueOf(userId));
        paramJson.put("timestamp", String.valueOf(Instant.now().getEpochSecond()));
        paramJson.put("app", StringUtils.isNotBlank(app) ? app : QUICK_AR_APP);
        paramJson.put("platform", StringUtils.isNotBlank(platform) ? platform : PLATFORM);
        paramJson.put("appid", APP_ID);
        String authorize = String.join("", paramJson.values());
        paramJson.put("service", UserConstant.WRITEOFF_WITH_AUTHORIZE);
        paramJson.put("authorize", DigestUtil.md5Hex(authorize + APP_SECRET));
        params.put("params", JSON.toJSONString(paramJson));
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        Object userServiceObject = genericService.$invoke("dubboRpc", paramTypes, paramValues);

        if (Objects.isNull(userServiceObject)) {
            throw new RuntimeException("删除用户失败！");
        }
        log.info("batchProfileByAuthorize response: {}", JSON.toJSONString(userServiceObject));
    }


    /**
     * 批量查询用户授权
     *
     * @param mobiles      用户手机号码
     * @param app          app
     * @param platform     平台
     * @param autoRegister 不存在是否自动注册
     * @return
     */
    public List<UserProfile> batchUserByMobileWithAuthorize(String app, String platform, List<String> mobiles, String autoRegister) {
        // 构建范化调用服务
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, String> params = new HashMap<>();
        Map<String, String> paramJson = new TreeMap<>();
        paramJson.put("mobile", JSONObject.toJSONString(mobiles));
        paramJson.put("timestamp", String.valueOf(Instant.now().getEpochSecond()));
        paramJson.put("app", StringUtils.isNotBlank(app) ? app : QUICK_AR_APP);
        paramJson.put("platform", StringUtils.isNotBlank(platform) ? platform : PLATFORM);
        paramJson.put("appid", APP_ID);
        paramJson.put("autoregister", autoRegister);
        String authorize = String.join("", paramJson.values());
        paramJson.put("service", UserConstant.BATCH_USER_BY_MOBILE_WITH_AUTHORIZE);
        paramJson.put("authorize", DigestUtil.md5Hex(authorize + APP_SECRET));
        params.put("params", JSON.toJSONString(paramJson));
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        Object userServiceObject = genericService.$invoke("dubboRpc", paramTypes, paramValues);
        if (Objects.nonNull(userServiceObject)) {
            log.info("batchProfileByAuthorize response: {}", JSON.toJSONString(userServiceObject));
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(userServiceObject));
            Integer stateCode = jsonObject.getInteger("ret");
            if (stateCode != 200) {
                throw new RuntimeException(jsonObject.getString("msg"));
            }

            JSONArray jsonArray = jsonObject.getJSONArray("data");
            List<UserProfile> userProfiles = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(jsonArray)) {
                for (Object o : jsonArray) {
                    UserProfile userProfile = JSON.parseObject(JSON.toJSONString(o), UserProfile.class);
                    userProfiles.add(userProfile);
                }
            }

            return userProfiles;
        }

        return null;
    }

    /**
     * 批量查询用户授权
     *
     * @param mobile       用户手机号码
     * @param app          app
     * @param platform     平台
     * @param autoRegister 不存在是否自动注册
     * @return
     */
    public UserProfile findUserByMobileWithAuthorize(String app, String platform, String mobile, String autoRegister) {
        // 构建范化调用服务
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, String> params = new HashMap<>();
        Map<String, String> paramJson = new TreeMap<>();
        paramJson.put("mobile", mobile);
        paramJson.put("timestamp", String.valueOf(Instant.now().getEpochSecond()));
        paramJson.put("app", StringUtils.isNotBlank(app) ? app : QUICK_AR_APP);
        paramJson.put("platform", StringUtils.isNotBlank(platform) ? platform : PLATFORM);
        paramJson.put("appid", APP_ID);
        paramJson.put("autoregister", autoRegister);
        String authorize = String.join("", paramJson.values());
        paramJson.put("service", UserConstant.FIND_USER_BY_MOBILE_WITH_AUTHORIZE);
        paramJson.put("authorize", DigestUtil.md5Hex(authorize + APP_SECRET));
        params.put("params", JSON.toJSONString(paramJson));
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        Object userServiceObject = genericService.$invoke("dubboRpc", paramTypes, paramValues);
        if (Objects.nonNull(userServiceObject)) {
            log.info("batchProfileByAuthorize response: {}", JSON.toJSONString(userServiceObject));
            String jsonStr = JSON.toJSONString(userServiceObject);
            JSONObject jsonObject = JSON.parseObject(jsonStr);
            Integer stateCode = jsonObject.getInteger("ret");
            if (stateCode.intValue() != 200) {
                return null;
            }

            return JSON.parseObject(JSON.toJSONString(jsonObject.get("data")), UserProfile.class);
        }

        return null;
    }

    /**
     * 批量查询用户授权
     *
     * @param userId   用户ID
     * @param app      app
     * @param platform 平台
     * @return
     */
    public List<UserProfile> batchProfileByAuthorize(List<Long> userId, String app, String platform) {
        // 构建范化调用服务
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, String> params = new HashMap<>();
        Map<String, String> paramJson = new TreeMap<>();
        paramJson.put("userids", JSON.toJSONString(userId));
        paramJson.put("timestamp", String.valueOf(Instant.now().getEpochSecond()));
        paramJson.put("app", StringUtils.isNotBlank(app) ? app : QUICK_AR_APP);
        paramJson.put("platform", StringUtils.isNotBlank(platform) ? platform : PLATFORM);
        paramJson.put("appid", APP_ID);
        String authorize = String.join("", paramJson.values());
        paramJson.put("service", UserConstant.BATCH_PROFILE_BY_AUTHORIZE);
        paramJson.put("authorize", DigestUtil.md5Hex(authorize + APP_SECRET));
        params.put("params", JSON.toJSONString(paramJson));
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        Object userServiceObject = genericService.$invoke("dubboRpc", paramTypes, paramValues);
        if (Objects.nonNull(userServiceObject)) {
            log.info("batchProfileByAuthorize response: {}", JSON.toJSONString(userServiceObject));
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(userServiceObject));
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            List<UserProfile> userProfiles = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(jsonArray)) {
                for (Object o : jsonArray) {
                    UserProfile userProfile = JSON.parseObject(JSON.toJSONString(o), UserProfile.class);
                    userProfiles.add(userProfile);
                }
            }
            return userProfiles;
        }
        return null;
    }

    /**
     * 构建范化调用服务
     *
     * @return 范化调用服务
     */
    private GenericService buildGenericService() {
        ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
        // 弱类型接口名
        reference.setApplication(new ApplicationConfig("user-provider"));
        //接口类全限定类名
        reference.setInterface("com.gxar.api.UserService");
        reference.setCheck(false);
        //接口版本号
        reference.setVersion("1.0.0");
        // 声明为泛化接口
        reference.setGeneric(true);
        reference.setSerialization("fastjson");
        // 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口引用
        ReferenceConfigCache cache = ReferenceConfigCache.getCache();
        return cache.get(reference);
    }
}
